package package1;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class TestForFolder {
	private static Scanner s = new Scanner(System.in);
	//sort @ 2016.4.30 including add "\\" after all the folder
	//attention: c:\\...desktop\\2\1 is neither folder nor file, should be 2\\1
	//attention: JVM doesn't know if File a = new File("1") is a file or a directory if it has not been created
	//家条件，复制文件或者文件夹，如果目标文件夹有，是否覆盖？??
	
	public static void main(String[] args) throws IOException, InterruptedException {
		String f1 = getDesktop()+"1\\1.txt";
		String f2 = getDesktop()+"2\\";
		File file1 = new File(f1);
//		File file2 = new File(f2);
//		makeNestingFoldersAndFiles();

		//????
		copyToFolder(f1,f2);//还要看一下，有问题呢！加起来，这里需要加“是否覆盖，好像逻辑比较复杂的”
		//????
		
		
//		copyFileToFile(f1,f2);
//		delete(f1);
//		deleteFolderContent(f1);
//		listFolderContent(f1);
//		searchFileOrFolderName(f1,"a");
//		writeToFile("1.txt","123");
//		openCurrentFolder();
	}

	//search file and folder
	public static void searchFileOrFolderName(Object o, String d) throws IOException {
		folderCheck(o);
		List<String> list  = new ArrayList<String>();
		searchFileOrFolder(toFile(o).listFiles(),d,list);
		if(list.size()==0)
			System.err.println("no result is found");
		else for(Object obj:list)System.err.println(obj.toString());
	}
	//search file and folder
	private static void searchFileOrFolder(File[] files, String d, List<String> list) {
		for(File file:files){
			if(file.getName().toLowerCase().contains(d.toLowerCase()))list.add(file.getAbsolutePath());
			if(file.isDirectory())searchFileOrFolder(file.listFiles(), d, list);
		}
	}

	
	
	//list folder content
	public static void listFolderContent(Object o) throws IOException {
		folderCheck(o);
		listFileAndFolder(toFile(o).listFiles(),0);
	}
	//list folder content
	private static void listFileAndFolder(File[] files,int layer) {
		for(File file:files){
			showName(file,layer);
			if(file.isDirectory()) listFileAndFolder(file.listFiles(), layer+1);
		}
	}
	//list folder content
	private static void showName(File file,int layer) {
		String start="",end=file.isDirectory()?"--↓":"--|";
		for(int i=0;i<layer;i++) start+="--";
		System.err.println(start+end+file.getName());
	}

	
	
	// copy file to file
	public static void copyFileToFile(Object o1, Object o2) throws IOException {
		//very difficult
		fileCheck(o1);
		//parent path is valid
		pathCheck(o2);
		//cannot be a folder
		if(toFile(o2).exists())
			if(!confirm("override",o2))return;
		if(toFile(o2).isDirectory())throw new IOException(o2.toString()+" is a folder");
		doCopyFile(toFile(o1), toFile(o2));
		System.err.println("success");
	}

	
	
	//copy file/folder to folder
	public static void copyToFolder(Object o1, Object o2) throws IOException {
		fileAndFolderCheck(o1,o2);
		folderCheck(o2);
		copyToFolder2(toFile(o1),toFile(o2));
	}

	

	//copy file/folder to folder
	private static void copyToFolder2(File file1, File folder2) throws IOException {
		if(file1.isFile()) doCopyFile(file1,new File(folder2,file1.getName()));
		else {
			File [] files = file1.listFiles();
			if(files.length==0)	return;
			doCopyFolder(files,folder2);
		}
	}
	//copy files[] to folder
	private static void doCopyFolder(File[] files, File folder2) throws IOException {
		//recursive of copying folder contents
		if(files.length==0)return;
		for(File file:files){
			if(file.isFile()){
				File file2 = new File(folder2+"\\"+file.getName());
				if(file2.exists())if(!confirm("override", file2))continue;
				doCopyFile(file, file2);
			}
			else{
				File folder = new File(folder2,file.getName());
				if(!folder.exists())folder.mkdirs();
				doCopyFolder(file.listFiles(), folder);
			}
		}
	}
	//copy file to file
	private static void doCopyFile(File f1, File f2) throws IOException {
		if(!f2.exists())f2.createNewFile();
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f1));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f2));
		byte [] b = new byte[1024];	int len;
		while((len=bis.read(b))!=-1)bos.write(b,0,len);
		bos.close();bis.close();
	}
	
	
	
	
	//delete folder area
	public static void delete(Object o) throws IOException {
		fileAndFolderCheck(o);
		if(!confirm("delete",o))return;
		File f = toFile(o);
		if(f.isDirectory())	doDeleteFolder(f);
		else f.delete();
		System.err.println("success");
	}
	//delete folder area
	private static void doDeleteFolder(File folder) throws IOException {
		for(File file:folder.listFiles()) if(file.isDirectory()) doDeleteFolder(file);else file.delete(); 
		folder.delete();
	}
	
	
	
	//delete folder content area
	public static void deleteFolderContent(Object o) throws IOException {
		folderCheck(o);
		if(!confirm("delete content",o))return;
		File[] files = new File((String) o).listFiles();
		if(files.length>0)doDeleteFolderContent(files);
		System.err.println("success");
	}
	//delete folder content area
	private static void doDeleteFolderContent(File[] files) throws IOException {
		for(File file:files){
			if(file.isDirectory())doDeleteFolder(file);
			else file.delete();
		}
	}
	
	
	
	//create folder and file for test
	public static void makeNestingFoldersAndFiles() throws IOException {
		String filePath = ".";//. = current folder
		String folderStr = "c.d.e";
		for(String fname:folderStr.split("\\.")) {
			String temp =filePath += "\\"+fname; 
			new File(temp).mkdirs();
			new File(temp+"\\1").createNewFile();
		}
		openCurrentFolder();
	}
	
	
	
	//log area
	public static void writeToFile(String fileName, String str) throws IOException {
		File f = new File(fileName);
		System.err.println("writeToFilepath:"+fileName);
		BufferedWriter bw = new BufferedWriter(new FileWriter(f));
		bw.write(str); bw.close();
	}

	
	//get consolo input
	private static String getConsoloInput() {
		return s.nextLine();
	}
	
	//confirm
	private static boolean confirm(String action, Object o) {
		if(action.equalsIgnoreCase("delete"));
		String warning = "are you sure to "+ action+" '"+o+"'? \r\nType 'y' to continue...";
		System.err.println(warning);
		String input = getConsoloInput();
		if(!input.equalsIgnoreCase("y")){
			System.err.println("abort "+action);
			return false;
		}
		return true;
	}
	
	//change obj -> file
	private static File toFile(Object o) {
		if(o instanceof String)return new File((String) o);
		else return (File) o;
	}
	
	//basic function parameter
	public static void openCurrentFolder() throws IOException {
		open(getCurrentFolder());
	}
	public static void open(String string) throws IOException {
		java.awt.Desktop.getDesktop().open(new File(string));
	}
	public static void open(File b) throws IOException {
		open(b.getAbsolutePath());
	}
	public static String getDesktop() {
		return System.getenv("USERPROFILE") + "\\desktop\\";
	}
	public static String getCurrentFolder() {
		return System.getProperty("user.dir")+"\\";
	}

	//check area
	private static boolean fileAndFolderCheck(Object...arr) throws IOException {
		for(Object obj:arr)	check(obj,"folderOrFile");
		return true;
	}
	private static boolean folderCheck(Object ...arr) throws IOException {
		for(Object obj:arr) check(obj,"folder");
		return true;
	}
	private static boolean fileCheck(Object ...arr) throws IOException {
		for(Object obj:arr) check(obj,"file");
		return true;
	}
	private static boolean pathCheck(Object ...arr) throws IOException {
		for(Object obj:arr) check(obj,"path");
		return true;
	}
	
	private static boolean check(Object obj, String type) throws IOException {
		if(obj==null)throw new IOException("imported object is null");
		File file;
		if(obj instanceof String)file = new File((String) obj);
		else if(obj instanceof File)file = (File) obj;
		else throw new IOException("The imported object is neither String nor File");
		if(type.equalsIgnoreCase("path")){
			if(!file.getParentFile().exists())throw new IOException(obj.toString()+" 's parent path does not exist");
		}else {
			if(!(file.isDirectory()||file.isFile())) throw new IOException(obj.toString()+" might not be existed");
			if(type.equalsIgnoreCase("folder")){
				if(!file.isDirectory())	throw new IOException(obj.toString()+" is not a directory");
			}
			if(type.equalsIgnoreCase("file")){
				if(!file.isFile())throw new IOException(obj.toString()+" is not a file");
			}
		}
		return true;
	}
}